home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C059B.ZIP / SRC1.ZIP / BONES.C < prev    next >
C/C++ Source or Header  |  1990-07-18  |  10KB  |  474 lines

  1. /*    SCCS Id: @(#)bones.c    3.0    88/04/13
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #define OMASK    0
  8.  
  9. #ifdef DGK
  10. char bones[FILENAME];
  11. extern long bytes_counted;
  12. #else
  13. char bones[] = "bones.xxxx";
  14. #endif
  15.  
  16. #ifdef COMPRESS
  17. static char cmd[60], proxy[20];
  18.  
  19. static void NDECL(compress_bones);
  20. #endif
  21. static boolean FDECL(no_bones_level, (int));
  22. static void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
  23. #ifdef TUTTI_FRUTTI
  24. static void FDECL(goodfruit, (int));
  25. #endif
  26.  
  27. #ifdef COMPRESS
  28. static void
  29. compress_bones()
  30. {
  31.     Strcpy(cmd, COMPRESS);
  32.     Strcat(cmd, " ");
  33. # ifdef COMPRESS_OPTIONS
  34.     Strcat(cmd, COMPRESS_OPTIONS);
  35.     Strcat(cmd, " ");
  36. # endif
  37.     Strcat(cmd, bones);
  38.     (void) system(cmd);
  39. }
  40. #endif /* COMPRESS */
  41.  
  42. static boolean
  43. no_bones_level(lev)
  44. int lev;
  45. {
  46.     extern int save_dlevel;        /* in do.c */
  47.  
  48.     if (save_dlevel) lev = save_dlevel;
  49.  
  50.     return (lev == medusa_level ||
  51.         lev == wiz_level
  52. #ifdef REINCARNATION
  53.         || lev == rogue_level
  54. #endif
  55. #ifdef STRONGHOLD
  56.         || lev == stronghold_level ||
  57.         (lev >= tower_level && lev <= tower_level+2)
  58. #endif
  59. #ifdef ENDGAME
  60.         || lev == ENDLEVEL
  61. #endif
  62.         );
  63. }
  64.  
  65. #ifdef TUTTI_FRUTTI
  66. static void
  67. goodfruit(id)
  68. int id;
  69. {
  70.     register struct fruit *f;
  71.  
  72.     for(f=ffruit; f; f=f->nextf) {
  73.         if(f->fid == -id) {
  74.             f->fid = id;
  75.             return;
  76.         }
  77.     }
  78. }
  79. #endif
  80.  
  81. static void
  82. resetobjs(ochain,restore)
  83. struct obj *ochain;
  84. boolean restore;
  85. {
  86.     struct obj *otmp;
  87.  
  88.     for (otmp = ochain; otmp; otmp = otmp->nobj) {
  89.         if (((otmp->otyp != CORPSE && otmp->otyp != STATUE)
  90.             || otmp->corpsenm < PM_ARCHEOLOGIST)
  91. #ifdef NAMED_ITEMS
  92.             && (!is_artifact(otmp) ||
  93.                 (exist_artifact(otmp,ONAME(otmp)) && restore))
  94. #endif
  95.         )
  96.             otmp->onamelth = 0;
  97. #ifdef NAMED_ITEMS
  98.         else if (is_artifact(otmp) && restore)
  99.             artifact_exists(otmp,ONAME(otmp),TRUE);
  100. #endif
  101.         if (!restore) {
  102.             /* resetting the o_id's after getlev has carefully
  103.              * created proper new ones via restobjchn is a Bad
  104.              * Idea */
  105.             otmp->o_id = 0;
  106.             if(objects[otmp->otyp].oc_uses_known) otmp->known = 0;
  107.             otmp->dknown = otmp->bknown = 0;
  108.             otmp->invlet = 0;
  109. #ifdef TUTTI_FRUTTI
  110.             if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  111. #endif
  112. #ifdef MAIL
  113.             if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
  114. #endif
  115. #ifdef POLYSELF
  116.             if (otmp->otyp == EGG) otmp->spe = 0;
  117. #endif
  118.             if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) {
  119.                 otmp->spe = -1;
  120.                 /* no longer the actual amulet */
  121.                 curse(otmp);
  122.             }
  123.         }
  124.     }            
  125. }
  126.  
  127. /* save bones and possessions of a deceased adventurer */
  128. void
  129. savebones(){
  130.     register int fd, x, y;
  131.     register struct obj *otmp;
  132.     register struct trap *ttmp;
  133.     register struct monst *mtmp, *mtmp2;
  134. #ifdef TUTTI_FRUTTI
  135.     struct fruit *f;
  136. #endif
  137.  
  138.     if(dlevel <= 0 || dlevel > MAXLEVEL) return;
  139.     if(no_bones_level(dlevel)) return; /* no bones for specific levels */
  140.     if(!rn2(1 + (dlevel>>2)) /* not so many ghosts on low levels */
  141. #ifdef WIZARD
  142.         && !wizard
  143. #endif
  144.         ) return;
  145. #ifdef EXPLORE_MODE
  146.     /* don't let multiple restarts generate multiple copies of objects
  147.      * in bones files */
  148.     if(discover) return;
  149. #endif
  150.  
  151.     name_file(bones, dlevel);
  152. #ifdef COMPRESS
  153.     Strcpy(proxy, bones);
  154.     Strcat(proxy, ".Z");
  155.  
  156.     if((fd = open(proxy, OMASK)) >= 0) {
  157. #else
  158.     if((fd = open(bones, OMASK)) >= 0) {
  159. #endif
  160.         (void) close(fd);
  161. #ifdef WIZARD
  162.         if(wizard)
  163.             pline("Bones file already exists.");
  164. #endif
  165.         return;
  166.     }
  167. #ifdef WALKIES
  168.     unleash_all();
  169. #endif
  170.     /* in case these characters are not in their home bases */
  171.     mtmp2 = fmon;
  172.     while((mtmp = mtmp2)) {
  173.         mtmp2 = mtmp->nmon;
  174.         if(mtmp->iswiz) mongone(mtmp);
  175. #ifdef MEDUSA
  176.         if(mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
  177. #endif
  178.     }
  179. #ifdef TUTTI_FRUTTI
  180.     /* mark all fruits as nonexistent; when we come to them we'll mark
  181.      * them as existing (using goodfruit())
  182.      */
  183.     for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
  184. #endif
  185.  
  186.     /* check iron balls separately--maybe they're not carrying it */
  187.     if (uball) uball->owornmask = uchain->owornmask = 0;
  188.  
  189.     /* drop everything; the corpse's possessions are usually cursed */
  190.     otmp = invent;
  191.     while(otmp) {
  192.         place_object(otmp, u.ux, u.uy);
  193.         otmp->owornmask = 0;
  194. #ifdef TUTTI_FRUTTI
  195.         if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  196. #endif
  197.         if(rn2(5)) curse(otmp);
  198.         if(!otmp->nobj){
  199.             otmp->nobj = fobj;
  200.             fobj = invent;
  201.             invent = 0;    /* superfluous */
  202.             break;
  203.         }
  204.         otmp = otmp->nobj;
  205.     }
  206.     in_mklev = TRUE;
  207.     /* tricks makemon() into allowing monster creation on your square */
  208.     if (u.ugrave_arise == -1) {
  209.         mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy);
  210.         in_mklev = FALSE;
  211.         if (!mtmp) return;
  212.         Strcpy((char *) mtmp->mextra, plname);
  213.     } else {
  214.         mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
  215.         in_mklev = FALSE;
  216.         if (!mtmp) return;
  217.         mtmp = christen_monst(mtmp, plname);
  218.         atl(u.ux, u.uy, mtmp->data->mlet);
  219.         Your("body rises from the dead as %s...",
  220.             an(mons[u.ugrave_arise].mname));
  221.     }
  222.     mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
  223.     mtmp->mhp = mtmp->mhpmax = u.uhpmax;
  224.     mtmp->msleep = 1;
  225.     if(u.ugold) mkgold(u.ugold, u.ux, u.uy);
  226.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
  227.         resetobjs(mtmp->minvent,FALSE);
  228.         mtmp->m_id = 0;
  229.         mtmp->mlstmv = 0L;
  230.         if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
  231.         if(mtmp->mdispl) unpmon(mtmp);
  232.     }
  233.     for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  234.         ttmp->tseen = 0;
  235.  
  236.     resetobjs(fobj,FALSE);
  237.     /* let's (not) forget about these - KCD, 10/21/89 */
  238.     resetobjs(fcobj,FALSE);
  239.  
  240.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
  241.         levl[x][y].seen = levl[x][y].new = levl[x][y].scrsym = 0;
  242.  
  243. #ifdef MSDOS
  244.     fd = open(bones, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
  245. #else
  246. # ifdef MACOS
  247.     {
  248.         Str255    fileName;
  249.         OSErr    er;
  250.         struct term_info    *t;
  251.         extern WindowPtr    HackWindow;
  252.         short    oldvolume;
  253.         
  254.         t = (term_info *)GetWRefCon(HackWindow);
  255.         (void)GetVol(&fileName,&oldvolume);
  256.         (void)SetVol(0L, t->recordVRefNum);
  257.         fileName[0] = (uchar)strlen(bones);
  258.         Strcpy((char *)&fileName[1],bones);
  259.         
  260.         if (er = Create(&fileName,0,CREATOR,BONES_TYPE))
  261.             SysBeep(1);
  262.         fd = open(bones,
  263.             O_WRONLY | O_BINARY | O_TRUNC | ((er) ? O_CREAT : 0));
  264.         (void)SetVol(0L, oldvolume);
  265.     }
  266. # else
  267.     fd = creat(bones, FCMASK);
  268. # endif /* MACOS */
  269. #endif
  270.     if(fd < 0) {
  271. #ifdef WIZARD
  272.         if(wizard)
  273.             pline("Cannot create bones file - creat failed");
  274. #endif
  275.         return;
  276.     }
  277.  
  278. #if defined(DGK)    /* check whether there is room */
  279.     count_only = TRUE;
  280. # ifdef TUTTI_FRUTTI
  281.     savefruitchn(fd);
  282. # endif
  283.     savelev(fd, dlevel, COUNT);
  284. # ifdef ZEROCOMP
  285.     bflush(fd);
  286. # endif
  287.     if (bytes_counted > freediskspace(bones)) {    /* not enough room */
  288. # ifdef WIZARD
  289.         if (wizard)
  290.             pline("Insufficient space to create bones file.");
  291. # endif
  292.         unlink(bones);
  293.         return;
  294.     }
  295.     count_only = FALSE;
  296. #endif /* DGK */
  297.  
  298. #ifdef TUTTI_FRUTTI
  299.     savefruitchn(fd);
  300. #endif
  301. #if defined(DGK)
  302.     savelev(fd, dlevel, WRITE);
  303. #else
  304.     savelev(fd,dlevel);
  305. #endif
  306. #ifdef ZEROCOMP
  307.     bflush(fd);
  308. #endif
  309.     (void) close(fd);
  310. #ifdef MACOS
  311.     {
  312.         FInfo    fndrInfo;
  313.         Str255    name;
  314.         term_info    *t;
  315.         short    oldVol, error;
  316.         
  317.         t = (term_info *)GetWRefCon(HackWindow);
  318.         GetVol(name, &oldVol);
  319.         SetVol(0L, t->recordVRefNum);  
  320.         Strcpy((char *)name, bones);
  321.         CtoPstr((char *)name);
  322.         error = GetFInfo(name, (short)0, &fndrInfo);
  323.         fndrInfo.fdCreator = CREATOR;
  324.         fndrInfo.fdType = BONES_TYPE;
  325.         if (error == noErr)
  326.             SetFInfo(name, (short)0, &fndrInfo);
  327.         SetVol(0L, oldVol);
  328.     }
  329. #endif
  330. #ifdef COMPRESS
  331.     compress_bones();
  332. #endif
  333. }
  334.  
  335. int
  336. getbones() {
  337.     register int fd;
  338.     register int ok;
  339. #ifdef MACOS
  340.     Str255    name;
  341.     short    oldVol;
  342.     term_info *t;
  343.     extern WindowPtr    HackWindow;
  344.     
  345.     t = (term_info *)GetWRefCon(HackWindow);
  346. #endif
  347. #ifdef EXPLORE_MODE
  348.     if(discover)        /* save bones files for real games */
  349.         return(0);
  350. #endif
  351.     /* wizard check added by GAN 02/05/87 */
  352.     if(rn2(3)    /* only once in three times do we find bones */
  353. #ifdef WIZARD
  354.         && !wizard
  355. #endif
  356.         ) return(0);
  357.     if(no_bones_level(dlevel)) return(0);
  358.     name_file(bones, dlevel);
  359. #ifdef MACOS
  360.     GetVol(name, &oldVol);
  361.     SetVol(0L, t->recordVRefNum);
  362. #endif
  363. #ifdef COMPRESS
  364.     if((fd = open(bones, OMASK)) >= 0) goto gotbones;
  365.     Strcpy(proxy, bones);
  366.     Strcat(proxy, ".Z");
  367.     if((fd = open(proxy, OMASK)) < 0) return(0);
  368.     else {
  369.         (void) close(fd);
  370.         Strcpy(cmd, COMPRESS);
  371.         Strcat(cmd, " -d ");    /* uncompress */
  372. # ifdef COMPRESS_OPTIONS
  373.         Strcat(cmd, COMPRESS_OPTIONS);
  374.         Strcat(cmd, " ");
  375. # endif
  376.         Strcat(cmd,proxy);
  377.         (void) system(cmd);
  378.     }
  379. #endif
  380.     if((fd = open(bones, OMASK)) < 0) {
  381. #ifdef MACOS
  382.         SetVol(0L, oldVol);
  383. #endif
  384.         return(0);
  385.     }
  386. #ifdef MACOS
  387.     SetVol(0L, oldVol);
  388. #endif
  389. #ifdef COMPRESS
  390. gotbones:
  391. #endif
  392.     if((ok = uptodate(fd)) != 0){
  393. #ifdef WIZARD
  394.         if(wizard)  {
  395.             pline("Get bones? ");
  396.             if(yn() == 'n') {
  397.                 (void) close(fd);
  398. # ifdef COMPRESS
  399.                 compress_bones();
  400. # endif
  401.                 return(0);
  402.             }
  403.         }
  404. #endif
  405. #ifdef ZEROCOMP
  406.         minit();
  407. #endif
  408.         getlev(fd, 0, dlevel, TRUE);
  409.     }
  410.     (void) close(fd);
  411. #ifdef NAMED_ITEMS
  412.     /* to correctly reset named artifacts on the level */
  413.     {
  414.         register struct monst *mtmp;
  415.  
  416.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  417.             resetobjs(mtmp->minvent,TRUE);
  418.         resetobjs(fobj,TRUE);
  419.         resetobjs(fcobj,TRUE);
  420.     }
  421. #endif
  422. #ifdef WIZARD
  423.     if(wizard) {
  424.         pline("Unlink bones? ");
  425.         if(yn() == 'n') {
  426. # ifdef COMPRESS
  427.             compress_bones();
  428. # endif
  429.             return(ok);
  430.         }
  431.     }
  432. #endif
  433. #ifdef MACOS
  434.     GetVol(name, &oldVol);
  435.     SetVol(0L, t->recordVRefNum);
  436. #endif
  437.     if(unlink(bones) < 0){
  438.         pline("Cannot unlink %s.", bones);
  439. #ifdef MACOS
  440.         SetVol(0L, oldVol);
  441. #endif
  442.         return(0);
  443.     }
  444. #ifdef MACOS
  445.     SetVol(0L, oldVol);
  446. #endif
  447.     return(ok);
  448. }
  449.  
  450. /* construct the string  file.level 
  451.  * This assumes there is space on the end of 'file' to append
  452.  * a two digit number.  This is true for 'bones' and 'level'
  453.  * but be careful if you use it for other things -dgk
  454.  */
  455. void
  456. name_file(file, lev)
  457. char *file;
  458. int lev;
  459. {
  460.     char *tf;
  461.  
  462.     if (tf = rindex(file, '.'))
  463. #ifdef VMS
  464.         Sprintf(tf+1, "%d;1", lev);
  465. #else
  466.           Sprintf(tf+1, "%d", lev);
  467. #endif
  468. #ifdef MSDOS /* for glo() */
  469.     else if (tf = eos(file))
  470.         Sprintf(tf, ".%d", lev);
  471. #endif
  472.     return;
  473. }
  474.